package com.mjkj.demo.core.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotRoleException;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;

import com.mjkj.demo.core.result.Result;
import com.mjkj.demo.core.result.ResultCode;
import com.mjkj.demo.core.result.ResultGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.file.AccessDeniedException;
import java.util.HashMap;
import java.util.List;

/**
 * 全局异常处理类
 *
 * @author cwh
 * @date 2023-01-07
 */

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 空指针异常
     */
    @ExceptionHandler(NullPointerException.class)
    public @ResponseBody
    Result nullPointerException(Exception ex) {
        log.error("发生异常",ex);
        return ResultGenerator.genFailResult("空指针异常！Null point error!");
    }

    /**
     * 权限不足
     */
    @ExceptionHandler(NotRoleException.class)
    public @ResponseBody
    Result notRoleException(Exception ex) {
        return ResultGenerator.genFailResult("权限不足！");
    }

    /**
     * 不止一条数据
     */
    @ExceptionHandler(TooManyResultsException.class)
    public @ResponseBody
    Result tooManyResultsException(Exception ex) {
        log.error("发生异常",ex);
        return ResultGenerator.genFailResult("数据查询异常！Too many result!");
    }

    /**
     * 全局未细化处理其它任何的错误信息处理
     */
    @ExceptionHandler(Exception.class)
    public @ResponseBody
    Result globalException(Exception ex) {
        log.error("发生异常",ex);
        return ResultGenerator.genFailResult("请联系双枪会给出答案");
    }

    /**
     * 未登录异常
     */
    @ExceptionHandler(NotLoginException.class)
    public @ResponseBody
    Result notLoginException(Exception ex) {
        return ResultGenerator.genFailResult("",ex.getMessage(), ResultCode.UNAUTHORIZED);
    }

    // 密码错误异常
   /* @ExceptionHandler(BadCredentialsException.class)
    public @ResponseBody
    Result BadCredentialsException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        Result result = ResultGenerator.genFailResult("用户名或密码错误");
        //ex.printStackTrace();
        return result;
    }*/

    /**
     * 请求体参数错误异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public @ResponseBody
    Result HttpMessageNotReadableException(Exception ex) {
        return ResultGenerator.genFailResult("请求体参数错误：" + ex.getMessage());
    }

    /**
     * 请求体参数错误异常
     */
    @ExceptionHandler(MismatchedInputException.class)
    public @ResponseBody
    Result MismatchedInputException(Exception ex) {
        return ResultGenerator.genFailResult("请求体参数格式错误" + ex.getMessage());
    }

    /**
     * 访问拒绝异常异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public @ResponseBody
    Result AccessDeniedException(Exception ex) {
        return ResultGenerator.genFailResult("", "该用户无权限访问", ResultCode.FORBIDDEN);
    }

    /**
     * 缺少请求参数异常
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public @ResponseBody
    Result MissingServletRequestParameterException(Exception ex) {
        return ResultGenerator.genFailResult(ex.getMessage());
    }

    /**
     * 全局未细化处理的错误信息
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public @ResponseBody
    Result NoHandlerFoundException(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException ex) {
        return ResultGenerator.genFailResult("接口 [" + request.getRequestURI() + "] 不存在");
    }


    /**
     * 捕捉参数校验的错误信息
     */
    @ExceptionHandler(BindException.class)
    public @ResponseBody
    Result BindException(BindException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        HashMap<String, String> errorFieldMap = new HashMap<>();
        for (FieldError fieldError : fieldErrors) {
            errorFieldMap.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        return ResultGenerator.genFailResult("参数传递错误，请检查格式或数据类型" + errorFieldMap);
    }

    /**
     * 参数校验的异常处理
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public @ResponseBody
    Result MethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        String message = ex.getMessage();
        String errorMsg = message.substring(message.lastIndexOf('[') + 1, message.lastIndexOf(']') - 1);
        return ResultGenerator.genFailResult(errorMsg);
    }

    /**
     * 上传文件大小超出范围
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public @ResponseBody
    Result MaxUploadSizeExceededException() {

        return ResultGenerator.genFailResult("文件过大!");
    }

    /**
     * 处理业务异常 ServiceException
     */
    @ExceptionHandler(value = ServiceException.class)
    public @ResponseBody
    Result ServiceException(ServiceException ex) {
        log.error("发生{}异常，{}",ex.getCode(),ex.getMessage());
        return ResultGenerator.genFailResult(null, ex.getMessage(), ex.getCode());
//        return ResultGenerator.genFailResult(ex.getMessage());
    }



}
